/*This file is part of PaperBall.

PaperBall is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

PaperBall is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with PaperBall.  If not, see <http://www.gnu.org/licenses/>.*/

package com.ran3000.paperball;

import java.util.List;

import javax.microedition.khronos.opengles.GL10;

import com.ran3000.paperball.World.WorldListener;
import com.ran3000.paperball.framework.Game;
import com.ran3000.paperball.framework.Input.TouchEvent;
import com.ran3000.paperball.framework.gl.Camera2D;
import com.ran3000.paperball.framework.gl.SpriteBatcher;
import com.ran3000.paperball.framework.impl.GLScreen;
import com.ran3000.paperball.framework.math.OverlapTester;
import com.ran3000.paperball.framework.math.Rectangle;
import com.ran3000.paperball.framework.math.Vector2;

public class GameScreen extends GLScreen {
	static final int GAME_READY = 0;
	static final int GAME_RUNNING = 1;
	static final int GAME_PAUSED = 2;
	static final int GAME_OVER = 3;
	
	int state;
	Camera2D guiCam;
	Vector2 touchPoint;
	SpriteBatcher batcher;
	World world;
	WorldListener worldListener;
	WorldRenderer renderer;
	Rectangle pauseButton;
	Rectangle resumeButton;
	Rectangle exitButton;
	Rectangle retryButton;
	int lastScore;
	String scoreString;
	
	public GameScreen(Game game) {
		super(game);
		state = GAME_READY;
		guiCam = new Camera2D(glGraphics, 1280, 800);
		touchPoint = new Vector2();
		batcher = new SpriteBatcher(glGraphics, 1000);
		worldListener = new WorldListener() {
			@Override
			public void explode() {
				Assets.playSound(Assets.explosionSound);
			}
		};
		world = new World(worldListener);
		renderer = new WorldRenderer(glGraphics, batcher, world);
		pauseButton = new Rectangle(5, 685, 110, 110);
		resumeButton = new Rectangle(400, 391, 480, 217);
		retryButton = new Rectangle(272, 266, 320, 108);
		exitButton = new Rectangle(624, 266, 320, 108);
		lastScore = 0;
		scoreString = "score: 0";
	}
	
	@Override
	public void update(float deltaTime) {
		
		switch(state) {
		case GAME_READY:
			updateReady();
			break;
		case GAME_RUNNING:
			updateRunning(deltaTime);
			break;
		case GAME_PAUSED:
			updatePaused();
			break;
		case GAME_OVER:
			updateGameOver();
			break;
		}
	}
	
	private void updateReady() {
		if(game.getInput().getTouchEvents().size() > 0) {
			state = GAME_RUNNING;
			Assets.playSound(Assets.startSound);
		}
	}
	
	private void updateRunning(float deltaTime) {
        Assets.playMusic();

		List<TouchEvent> touchEvents = game.getInput().getTouchEvents();
		int len = touchEvents.size();
		for(int i = 0; i < len; i++) {
			TouchEvent event = touchEvents.get(i);
			if(event.type != TouchEvent.TOUCH_UP)
				continue;
			
			touchPoint.set(event.x, event.y);
			guiCam.touchToWorld(touchPoint);
			
			if(OverlapTester.pointInRectangle(pauseButton, touchPoint)) {
				Assets.playSound(Assets.clickSound);
				state = GAME_PAUSED;
				return;
			}
		}
		
		world.update(deltaTime, game.getInput().getAccelY());
		if(world.score != lastScore) {
			lastScore = world.score;
			scoreString = "score:" + lastScore;
		}
		if(world.state == World.WORLD_STATE_GAME_OVER) {
			state = GAME_OVER;
			if(lastScore >= Settings.highscores[4])
				scoreString = "new highscore: " + lastScore;
			else
				scoreString = "score: " + lastScore;

            Settings.addScore(lastScore);
		}
		
		if(lastScore == 30)
			world.nBombs = 4;
		if(lastScore == 70)
			world.nBombs = 5;
		if(lastScore == 120)
			world.nBombs = 6;
		if(lastScore == 200)
			world.nBombs = 7;
		if(lastScore == 0)
			world.nBombs = 3;
	}
	
	private void updatePaused() {
        Assets.stopMusic();

		List<TouchEvent> touchEvents = game.getInput().getTouchEvents();
		int len = touchEvents.size();
		for(int i = 0; i < len; i++) {
			TouchEvent event = touchEvents.get(i);
			if(event.type != TouchEvent.TOUCH_UP)
				continue;
			touchPoint.set(event.x, event.y);
			guiCam.touchToWorld(touchPoint);
			
			if(OverlapTester.pointInRectangle(resumeButton, touchPoint)) {
				Assets.playSound(Assets.clickSound);
				state = GAME_RUNNING;
				return;
			}
			
			if(OverlapTester.pointInRectangle(retryButton, touchPoint)) {
				Assets.playSound(Assets.clickSound);
				if(lastScore >= Settings.highscores[4])
					scoreString = "new highscore: " + lastScore;
				else
					scoreString = "score: " + lastScore;
				lastScore = 0;
				retry();
			}
			
			if(OverlapTester.pointInRectangle(exitButton, touchPoint)) {
				Assets.playSound(Assets.clickSound);
				game.setScreen(new MainMenuScreen(game));
				return;
			}
		}
	}
	
	private void updateGameOver() {
        Assets.stopMusic();

		List<TouchEvent> touchEvents = game.getInput().getTouchEvents();
		int len = touchEvents.size();
		for(int i = 0; i < len; i++) {
			TouchEvent event = touchEvents.get(i);
			if(event.type != TouchEvent.TOUCH_UP)
				continue;
			
			touchPoint.set(event.x, event.y);
			guiCam.touchToWorld(touchPoint);
			
			if(OverlapTester.pointInRectangle(retryButton, touchPoint)) {
				Assets.playSound(Assets.clickSound);
				if(lastScore >= Settings.highscores[4])
					scoreString = "new highscore: " + lastScore;
				else
					scoreString = "score: " + lastScore;
				Settings.addScore(lastScore);
				lastScore = 0;
				retry();
			}
			
			if(OverlapTester.pointInRectangle(exitButton, touchPoint)) {
				Assets.playSound(Assets.clickSound);
				game.setScreen(new MainMenuScreen(game));
				return;
			}
		}
	}
	
	private void retry()  {
		game.setScreen(new GameScreen(game));
		return;
	}
	
	@Override
	public void present(float deltaTime) {
		GL10 gl = glGraphics.getGL();
		gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
		gl.glEnable(GL10.GL_TEXTURE_2D);
		
		renderer.render();
		
		guiCam.setViewportAndMatrices();
		gl.glEnable(GL10.GL_BLEND);
		gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);
		switch(state) {
		case GAME_READY:
			presentReady();
			break;
		case GAME_RUNNING:
			presentRunning();
			break;
		case GAME_PAUSED:
			presentPaused();
			break;
		case GAME_OVER:
			presentGameOver();
			break;
		}
		gl.glDisable(GL10.GL_BLEND);
	}
	
	private void presentReady() {
		batcher.beginBatch(Assets.items);
		batcher.drawSprite(640, 400, 1280, 800, Assets.transparency);
		batcher.drawSprite(640, 400, 720, 307, Assets.ready);
		batcher.endBatch();
	}
	
	private void presentRunning() {
		batcher.beginBatch(Assets.items);
		batcher.drawSprite(60, 740, 110, 110, Assets.pauseButton);
		Assets.font.drawText(batcher, scoreString, 150, 740);
		batcher.endBatch();
	}
	
	private void presentPaused() {
		batcher.beginBatch(Assets.items);
		batcher.drawSprite(640, 400, 1280, 800, Assets.transparency);
		batcher.drawSprite(640, 500, 480, 217, Assets.playButton);
		batcher.drawSprite(432, 320, 320, 108, Assets.retryButton);
		batcher.drawSprite(784, 320, 320, 108, Assets.exitButton);
		Assets.font.drawText(batcher, scoreString, 60, 740);
		batcher.endBatch();
	}
	
	private void presentGameOver() {
		batcher.beginBatch(Assets.items);
		batcher.drawSprite(640, 400, 1280, 800, Assets.transparency);
		batcher.drawSprite(640, 500, 627, 160, Assets.gameOver);
		batcher.drawSprite(432, 320, 320, 108, Assets.retryButton);
		batcher.drawSprite(784, 320, 320, 108, Assets.exitButton);
		Assets.font.drawText(batcher, scoreString, 60, 740);
		batcher.endBatch();
	}
	
	@Override
	public void pause() {
		if(state == GAME_RUNNING)
			state = GAME_PAUSED;
	}
	
	@Override
	public void resume() {
	}
	
	@Override
	public void dispose() {
	}
}
